<template>
	<div class="container">
		<Menu
			class="titleHeader"
			v-if="showMenu|true"
			:contextPos="contextPos"
			@menyItemCmd="menyItemCmd"
			:selectedCells="selectedCells"
		/>
		<div class="tableContent">
			<div ref="tableContentBody" class="tableContentBody">
				<Scroll
					ref="ivScroll1"
					class="ivScroll1"
					:height="scrollHeight1"
					:class="{scrollMain:scrollMain1}"
				>
					<table class="table">
						<tbody class="table-body" v-if="JSON.stringify(tableData)== '{}'">
							<tr
								class="table-list"
								v-for="(row, index) in tableData.rows"
								:style="{height:tableData.layoutRows[index].height}"
								:key="index"
							>
								<td
									class="table-item"
									v-for="(col, index) in tableData.cols"
									:class="{selected: selectedCells.includes((row - 1) * tableData.cols + col - 1)}"
									:key="index"
									:colspan="tableData.layoutDetail[(row - 1) * tableData.cols + col - 1] && tableData.layoutDetail[(row - 1) * tableData.cols + col - 1]['colSpan']"
									:rowspan="tableData.layoutDetail[(row - 1) * tableData.cols + col - 1] && tableData.layoutDetail[(row - 1) * tableData.cols + col - 1]['rowSpan']"
									:style="{width:tableData.layoutDetail[(row - 1) * tableData.cols + col - 1] && tableData.layoutDetail[(row - 1) * tableData.cols + col - 1]['width']}"
									v-show="isNeedShow(row-1, col-1)"
									@mousedown="e => handleCellMousedown(e, row, col)"
									@mouseenter.stop.prevent="handleCellMouseenter(row, col)"
									@mouseup="handleMouseUp"
								>{{tableData.layoutDetail[(row - 1) * tableData.cols + col - 1] && tableData.layoutDetail[(row - 1) * tableData.cols + col - 1]['content']}}--{{ col }}--{{(row - 1) * tableData.cols + col - 1}}--{{selectedCells.includes((row - 1) * tableData.cols + col - 1)}}</td>
							</tr>
						</tbody>
					</table>
				</Scroll>
			</div>
		</div>
	</div>
</template>
<script>
import Menu from './Menu'
export default {
	props: {
		pagesContent: {
			type: Object,
			default: function () {
				return {}
			},
		},
	},
	data() {
		return {
			scrollHeight1: '100%',
			scrollMain1: false, //是否 显示
			// 这块其实初始设置 tableData： {cols: 3, rows: 2} 就可以 把tabelDate设置成计算属性，layoutDetail 用js生成更方便
			template: {
				layoutRows: {
					height: '200px',
				},
				layoutDetail: {
					containerId: '',
					colSpan: 1,
					rowSpan: 1,
					content: '',
					width: 'auto',
				},
			},
			tableData: {},
			selectedCells: [],
			// mousedown的时候设置为其他值 否则都是-1
			selectionHold: -1,
			startX: -1,
			startY: -1,
			endX: -1,
			endY: -1,
			showMenu: false,
			contextPos: {
				l: 0,
				t: 0,
			},
		}
	},
	components: {
		Menu,
	},
	created() {},
	watch: {
		pagesContent(val) {
			this.tableData = val
		},
	},
	computed: {
		hiddenTdMaps() {
			let hiddenTdMaps = {}
			let tableData = this.tableData
			for (let i = 0; i < tableData.rows; i++) {
				for (let j = 0; j < tableData.cols; j++) {
					if (tableData.layoutDetail[i * tableData.cols + j]) {
						let colInfo =
							tableData.layoutDetail[i * tableData.cols + j]
						if (
							(colInfo.colSpan && colInfo.colSpan > 1) ||
							(colInfo.rowSpan && colInfo.rowSpan > 1)
						) {
							for (
								let row = i;
								row < i + (colInfo.rowSpan || 1);
								row++
							) {
								// col = (row === i ? j + 1 : j) 是为了避开自己
								for (
									let col = row === i ? j + 1 : j;
									col < j + (colInfo.colSpan || 1);
									col++
								) {
									hiddenTdMaps[`${row}_${col}`] = true
								}
							}
						}
					}
				}
			}
			return hiddenTdMaps
		},
	},
	methods: {
		clearSelection() {
			this.selectedCells = []
		},
		changeShowMenu() {
			this.showMenu = !this.showMenu
		},
		isNeedShow(row, col) {
			return !this.hiddenTdMaps[`${row}_${col}`]
		},
		handleCellMousedown(e, x, y) {
			this.showMenu = false
			if (e.which === 1) {
				this.endX = this.endY = -1
			}
			// e.witch = 1 是鼠标左键
			if (e.which !== 1) return
			let cellIndex = (x - 1) * this.tableData.cols + y - 1
			this.startX = x
			this.startY = y
			this.selectedCells = [cellIndex]
			// mousedown标志
			this.selectionHold = cellIndex
		},
		handleCellMouseenter(x, y) {
			if (this.selectionHold != -1) {
				this.endX = x
				this.endY = y
				this.rendSelectedCell()
			}
		},
		rendSelectedCell() {
			let startX = Math.min(this.startX, this.endX)
			let startY = Math.min(this.startY, this.endY)
			let endX = Math.max(this.startX, this.endX)
			let endY = Math.max(this.startY, this.endY)
			let tableData = this.tableData
			let selectedCells = []
			for (let row = 1; row <= tableData.rows; row++) {
				for (let col = 1; col <= tableData.cols; col++) {
					if (
						row >= startX &&
						row <= endX &&
						col >= startY &&
						col <= endY
					) {
						selectedCells.push(
							(row - 1) * this.tableData.cols + col - 1
						)
					}
				}
			}
			this.selectedCells = selectedCells
		},
		handleMouseUp(e) {
			this.selectionHold = -1
		},
		handleContendMenu(e) {
			this.showMenu = true
			this.contextPos.l = e.pageX
			this.contextPos.t = e.pageY
		},
		reRenderTableLayout(selected, option, operation, data1) {
			//选择  行列  加减
			let arr = [] //空数组保存位置
			let num = selected[0] //点击位置
			let data = data1 //保存操作数据
			let ceil = Math.ceil((num + 1) / this.tableData.cols) //求行
			let colNum = Math.ceil((num + 1) % this.tableData.cols) //求余  获得 列数    1.。。。。n-1，n=0 n为整除
			let n = 0 //列数
			if (operation == 'reduce') {
				if (option == 'rows') {
					//删除行    功能点
					for (let i = 0; i < this.tableData.cols; i++) {
						//列数遍历删除
						data.layoutDetail.splice(
							ceil * this.tableData.cols - 1 - i,
							1
						)
					}
					this.tableData = data
				} else if (option == 'cols') {
					//删除列  功能点
					if (colNum == 0) {
						n = this.tableData.cols
					} else {
						n = colNum
					}
					for (let i = this.tableData.rows - 1; i >= 0; i--) {
						//列数遍历删除
						data.layoutDetail.splice(
							n - 1 + i * this.tableData.cols,
							1
						)
					}
					this.tableData = data
				}
			} else if (operation == 'plus') {
				if (selected.length == 0) {
					//未选中的时候也可以添加
					if (option == 'rows') {
						data.layoutRows.unshift(this.template.layoutRows) //前插入
						for (let i = 0; i < this.tableData.cols; i++) {
							//列数遍历
							data.layoutDetail.unshift(
								this.template.layoutDetail
							)
						}
						this.tableData = data
					} else if (option == 'cols') {
						//前插入
						n = 1
						for (let i = this.tableData.rows - 1; i >= 0; i--) {
							//列数遍历    前插入
							arr.push(n - 1 + i * this.tableData.cols)
							data.layoutDetail.splice(
								n - 1 + i * this.tableData.cols,
								0,
								this.template.layoutDetail
							)
						}
						this.tableData = data
					}

					return
				}
				if (option == 'rows') {
					//添加行  功能点
					//行 列 点点

					data.layoutRows.splice(ceil, 0, this.template.layoutRows) //后插入
					for (let i = 0; i < this.tableData.cols; i++) {
						//列数遍历
						arr.push(this.template.layoutDetail)
					}
					data.layoutDetail.splice(
						ceil * this.tableData.cols * ceil,
						0,
						...arr
					)
					this.tableData = data
				} else if (option == 'cols') {
					//添加列  功能点
					//行 列 点点
					if (colNum == 0) {
						n = this.tableData.cols
					} else {
						n = colNum
					}
					for (let i = this.tableData.rows - 1; i >= 0; i--) {
						//列数遍历    后插入
						data.layoutDetail.splice(
							n - 1 + i * this.tableData.cols + 1,
							0,
							this.template.layoutDetail
						)
					}
					this.tableData = data
				}
			}
		},
		rowHeight() {
			console.log(1)
		},
		colWidth() {
			console.log(2)
		},
		delOption(
			selected,
			option,
			operation,
			tips1 = '请选择删除项!',
			tips2 = '不支持多选删除!'
		) {
			let data = JSON.parse(JSON.stringify(this.tableData))
			if (selected.length == 1) {
				//修改长度
				if (operation == 'reduce') {
					if (option == 'rows') {
						data.layoutRows.splice(selected[0], 1)
					}
					data[option] = data[option] - 1
				} else if (operation == 'plus') {
					if (option == 'rows') {
						data.layoutRows.splice(
							selected[0],
							0,
							this.template.layoutRows
						)
					}
					data[option] = data[option] + 1
				}
				this.reRenderTableLayout(selected, option, operation, data)
				this.clearSelection()
			} else if (selected.length == 0) {
				//等于零时候   为 行 列 加
				if (
					(operation == 'plus' && option == 'rows') |
					(operation == 'plus' && option == 'cols')
				) {
					if (operation == 'reduce') {
						if (option == 'rows') {
							data.layoutRows.splice(selected[0], 1)
						}
						data[option] = data[option] - 1
					} else if (operation == 'plus') {
						if (option == 'rows') {
							data.layoutRows.splice(
								selected[0],
								0,
								this.template.layoutRows
							)
						}
						data[option] = data[option] + 1
					}
					this.reRenderTableLayout(selected, option, operation, data)
				} else {
					this.$Message.warning(tips1)
				}
			} else if (selected.length < 1) {
				this.$Message.warning(tips1)
			} else if (selected.length > 1) {
				this.$Message.warning(tips2)
			}
		},
		menyItemCmd(cmd, selected) {
			let tableData = this.tableData
			let startX = Math.min(this.startX, this.endX)
			let startY = Math.min(this.startY, this.endY)
			let endX = Math.max(this.startX, this.endX)
			let endY = Math.max(this.startY, this.endY)
			switch (cmd) {
				case 'merge':
					if (
						startX === -1 ||
						startY === -1 ||
						endX === -1 ||
						endY === -1 ||
						(startX === endX && startY === endY)
					)
						return
					let startIndex = (startX - 1) * tableData.cols + startY - 1
					this.tableData.layoutDetail[startIndex].rowSpan =
						endX - startX + 1
					this.tableData.layoutDetail[startIndex].colSpan =
						endY - startY + 1
					this.clearSelection()
					break
				case 'split':
					this.tableData.layoutDetail.forEach((v) => {
						v.rowSpan = 1
						v.colSpan = 1
					})
					this.clearSelection()
					break
				case 'delRow':
					this.delOption(selected, 'rows', 'reduce')
					break
				case 'delCol':
					this.delOption(selected, 'cols', 'reduce')
					break
				case 'addRow':
					this.delOption(
						selected,
						'rows',
						'plus',
						'请选择添加项!',
						'不支持多选!'
					)
					break
				case 'addCol':
					this.delOption(
						selected,
						'cols',
						'plus',
						'请选择添加项!',
						'不支持多选!'
					)
					break
				case 'rowHeight':
					this.rowHeight()
					break
				case 'colWidth':
					this.colWidth()
					break
				case 'clearSelection':
					this.clearSelection()
					break
			}
			this.changeShowMenu()
		},
	},
	mounted() {
		this.scrollHeight1 = this.$refs.tableContentBody.offsetHeight
		//	this.pagesContent=

		this.tableData = {
			cols: 3, //列
			rows: 5, //行
			layoutDetail: [
				{
					containerId: '11',
					colSpan: 1, //合并列
					rowSpan: 1, //合并行
					content: '77', //模块内容
					width: '33.33%', //列宽
					height: '200px', //行高
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '66',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '55',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '44',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '33',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '22',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '44',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '33',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '22',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '44',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '33',
					width: '33.33%',
					height: '200px',
				},
				{
					containerId: '11',
					colSpan: 1,
					rowSpan: 1,
					content: '22',
					width: '33.33%',
					height: '200px',
				},
				{
					colSpan: 1,
					rowSpan: 1,
					content: '44',
					width: '33.33%',
					height: '200px',
					containerId: '11',
				},
				{
					colSpan: 1,
					rowSpan: 1,
					content: '33',
					width: '33.33%',
					height: '200px',
					containerId: '11',
				},
				{
					colSpan: 1,
					rowSpan: 1,
					content: '231123d',
					width: '33.33%',
					height: '200px',
					containerId: '11',
				},
			],
		}
	},
}
</script>

<style lang='less'>
.container {
	-webkit-touch-callout: none; /* iOS Safari */
	-webkit-user-select: none; /* Chrome/Safari/Opera */
	-khtml-user-select: none; /* Konqueror */
	-moz-user-select: none; /* Firefox */
	-ms-user-select: none; /* Internet Explorer/Edge */
	user-select: none; /* Non-prefixed version, currently*/
	position: relative;
	width: 100%;
	height: 100%;
	.titleHeader {
		position: absolute;
		z-index: 2;
		width: 100%;
		height: 50px;
	}
	.tableContent {
		width: 100%;
		height: 100%;
		padding-top: 50px;
	}
	.tableContentBody {
		width: 100%;
		height: 100%;
	}
	.table {
		border-collapse: collapse;
		width: 100%;
		// height: 100%;

		.table-body {
			.table-list {
				height: 50px;
				line-height: 50px;
				//&:hover{
				//  background:#eef1f6;
				//}
				td {
					padding: 0 10px;
					border: 1px dashed #dfe6ec;

					&.selected {
						background: #d4e7f5;
					}
				}
			}
		}
	}
}
.ivScroll1 ::-webkit-scrollbar {
	display: none;
}
</style>